/*
 * Ingenic IMP AUDIO_COMMON implement.
 *
 * Copyright (C) 2017 Ingenic Semiconductor Co.,Ltd
 *
 */
#include <imp/imp_log.h>

#include <stdio.h>
#include <math.h>
#include "audio_process.h"


#define  TAG "audio_common"
#define MAX_16BIT 32767
#define MIN_16BIT -32767
#define PI 3.1415926
#define sqrt_2 1.4142


audio_dev_info_t g_audio_dev_info = {0, 0};

const int16_t kFilterCoefficients8kHz[5] =
         {3798, -7596, 3798, 7807, -3733};//bk
         /* {3875, -7750, 3875, 7737, -3665}; /100
			   172         * {3768, -7536, 3768, 7511, -3467};//150*/
         /* {3665, -7330, 3665, 7285, -3280};//200*/
         /* {3565, -7130, 3565, 7061, -3103};//250 */
         /* {3279, -6558, 3279, 6394, -2627};//400*/
         /* {3101, -6202, 3101, 5957, -2351};//500 */
         /* {2331, -4662, 2331, 3862, -1365};//1000 */

const int16_t kFilterCoefficients[5] =
     /* {3096, -6192, 3096, 2972, -1172};//bk*/
	{3665, -7330, 3665, 7285, -3280};//400
     /* {3101, -6202, 3101, 5956, -2351};//1000 */
     /* {2617, -5234, 2617, 2341, -846}; */
     /* {4012, -8024, 4012, 8002, -3913}; */

void _audio_set_volume(char *src, char *dst, int size, int pcmbit, double exv)
{
	unsigned char temp8;
	short temp16;
	int temp32;
	unsigned int i;

	switch (pcmbit) {
		case 16:
			{
				short *psrc = (short *)src;
				short *pdst = (short *)dst;

				for (i = 0; i < size/2; i++) {
					temp16 = psrc[i];
					temp16 = (double)temp16 * exv;
#if 1
					temp32 =  psrc[i] * exv;
					if (temp32 > MAX_16BIT)
						temp16 = MAX_16BIT;
					else if (temp32 < MIN_16BIT)
						temp16 = MIN_16BIT;
#endif
#if 0
					if (exv >= 0)
						temp16 = psrc[i] << exv;
					else
						temp16 = psrc[i] >> abs(exv);
					if (temp16 > MAX_16BIT)
						temp16 = MAX_16BIT;
					else if (temp16 < MIN_16BIT)
						temp16 = MIN_16BIT;
#endif
					pdst[i] = temp16;
				}
			}
			break;
		case 8:
			for (i = 0; i < size; i++)
			{
				temp8 = src[i];
				temp8 = (double)temp8 * exv;

#if 0
				if (exv >= 0)
					temp8 = temp8 << exv;
				else
					temp8 = temp8 >> abs(exv);
#endif
				dst[i] = temp8;
			}
			break;
		default:
			IMP_LOG_ERR(TAG, "error pcmbit \n");
	}
}

int init_audioProcess_library(const char *libFileName, void **handle)  //initializefilter loadlibrary
{
	const char *defaultDir[2] = {"/usr/lib","/lib"};
	const char *env = getenv("LD_LIBRARY_PATH");

	if(NULL == *handle) {
		*handle = load_audioProcess_library(defaultDir, 2, libFileName, env);
		if(NULL == *handle) {
			printf("Usage:please check file:libaudioProcess.so is in path of /lib or /usr/lib\n");
			printf("If you put file:libaudioProcess.so in your defined path:\n");
			printf("  you need to set the enviroment variable LD_LIBRARY_PATH\n");
			IMP_LOG_ERR(TAG,"fun:%s,load shared library failed\n",__func__);
			return -1;
		}
	}
 	return 0;
}

int deinit_audioProcess_library(void **handle)  //deinit audioProcess library
{
	int ret = free_audioProcess_library(*handle);

	if(ret != 0)
		IMP_LOG_ERR(TAG,"fun:%s,free audioProcess library failed\n", __func__);

	*handle = NULL;
	return ret;

}

int Hpf_Version(char *versionStr, char length)
{
	char version[] = "Ingenic High Pass Filter 1.1.0";
	char versionLen = (char)strlen(version) + 1;

	if (versionStr == NULL){
		return -1;
	}

	if(versionLen > length) {
		return -1;
	}

	strncpy(versionStr, version, versionLen);
	return 0;
}

void Hpf_gen_filter_coefficients(short* coef, int samplerate, int p_rate)
{
	float cutoff = p_rate;
	float sample_rate = samplerate;
	float omiga_s = tan(cutoff/sample_rate*PI);
	float a = omiga_s*omiga_s + sqrt_2*omiga_s + 1;
	float b = 2*omiga_s*omiga_s - 2;
	float c = omiga_s*omiga_s - sqrt_2*omiga_s + 1;
	b=-b/a;
	c=-c/a;
	float d=1/a;
	coef[0]= d*4096;
	coef[1]=-coef[0]*2;
	coef[2]=coef[0];
	coef[3]=b*4096;
	coef[4]=c*4096;
}
